<template>
  <div>
    <a-card>
      <a-button type="primary" :icon="h(PlusOutlined)" class="mb-4" @click="handleAdd">
        添加
      </a-button>
      <a-table
        v-if="showTable"
        :columns="columns"
        :data-source="tree"
        :loading="tableLoading"
        :row-key="(row) => row.menuId + ''"
        default-expand-all-rows
        expandRowByClick
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.dataIndex === 'menuTypeLabel'">
            <FileOutlined v-if="record.menuType === MenuTypeEnum.PAGE" />
            <FolderOpenOutlined v-else-if="record.menuType === MenuTypeEnum.DIR" />
            <YoutubeOutlined v-else />
            {{ record.menuTypeLabel }}
          </template>
          <template v-if="column.dataIndex === 'actions'">
            <a-button
              v-if="record.menuType !== MenuTypeEnum.BTN"
              size="small"
              type="link"
              @click.stop="handleAdd(record)"
            >
              <a-tooltip>
                <template #title>添加</template>
                <PlusOutlined />
              </a-tooltip>
            </a-button>
            <a-button size="small" type="link" @click.stop="handleEdit(record)">
              <a-tooltip>
                <template #title>编辑</template>
                <EditOutlined />
              </a-tooltip>
            </a-button>
            <a-button size="small" type="link" danger @click.stop="handleDelete(record)">
              <a-tooltip>
                <template #title>删除</template>
                <DeleteOutlined />
              </a-tooltip>
            </a-button>
          </template>
        </template>
      </a-table>
    </a-card>
    <a-modal
      v-model:open="showModal"
      :mask-closable="false"
      :title="title"
      :confirm-loading="formBtnLoading"
      @ok="handleConfirm"
    >
      <a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" class="pt-1">
        <a-form-item label="菜单类型" name="menuType">
          <a-select
            v-model:value="form.menuType"
            placeholder="请选择菜单类型"
            :options="menuTypeOpts"
          />
        </a-form-item>
        <a-form-item label="菜单名称" name="menuName">
          <a-input
            v-model:value="form.menuName"
            allow-clear
            show-count
            :maxlength="15"
            placeholder="请输入菜单名称"
          />
        </a-form-item>
        <a-form-item v-if="form.menuType !== MenuTypeEnum.DIR" label="菜单权限" name="permission">
          <a-input v-model:value="form.permission" allow-clear placeholder="请输入菜单权限" />
        </a-form-item>
        <a-form-item v-if="form.menuType !== MenuTypeEnum.DIR" label="父级菜单" name="parentId">
          <a-select
            v-model:value="form.parentId"
            placeholder="请选择父级菜单"
            option-filter-prop="label"
            :options="parentOpts"
          />
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
  import { computed, h, onMounted, reactive, ref } from 'vue';
  import MenuApi from '@/api/MenuApi';
  import {
    PlusOutlined,
    DeleteOutlined,
    EditOutlined,
    FileOutlined,
    FolderOpenOutlined,
    YoutubeOutlined,
  } from '@ant-design/icons-vue';
  import { MenuTypeEnum } from '@/enums/commEnum';
  import { message, Modal } from 'ant-design-vue';
  import { Rule } from 'ant-design-vue/es/form';
  import { resetReactive } from '@/utils';

  let columns = [
    { title: '菜单名称', dataIndex: 'menuName' },
    { title: '菜单权限', dataIndex: 'permission' },
    { title: '菜单类型', dataIndex: 'menuTypeLabel' },
    { title: '创建时间', dataIndex: 'createTime' },
    { title: '更新时间', dataIndex: 'updateTime' },
    {
      title: '操作',
      dataIndex: 'actions',
      align: 'center',
    },
  ];
  const menuTypeOpts = [
    {
      label: '目录',
      value: 'DIR',
    },
    {
      label: '页面',
      value: 'PAGE',
    },
    {
      label: '按钮',
      value: 'BTN',
    },
  ];
  const parentOpts = computed(() => {
    return data.value
      .filter((i: Menu) => {
        if (form.menuType === MenuTypeEnum.PAGE) return i.menuType === MenuTypeEnum.DIR;
        return i.menuType === MenuTypeEnum.PAGE;
      })
      .map((i: Menu) => {
        return {
          label: i.menuName,
          value: i.menuId,
        };
      });
  });
  let data = ref([]);
  let tree = ref([]);
  onMounted(() => {
    getList();
  });

  const tableLoading = ref(false);
  const showTable = ref(false);

  function getList() {
    tableLoading.value = true;
    MenuApi.listAndTree()
      .then((res) => {
        data.value = res.data[0].list;
        tree.value = res.data[0].tree;
      })
      .finally(() => {
        tableLoading.value = false;
        showTable.value = true;
      });
  }

  const showModal = ref(false);
  const title = ref('');
  const formRef = ref();
  const form = reactive<Menu>({
    parentId: 0,
    menuName: '',
    menuType: MenuTypeEnum.PAGE,
    permission: '',
  });
  const rules: Record<string, Rule[]> = {
    menuName: [{ required: true, trigger: 'blur', message: '请输入' }],
  };

  function handleEdit(row) {
    showModal.value = true;
    title.value = '编辑';
    Object.assign(form, row);
    formRef.value?.clearValidate();
  }

  function handleAdd(record) {
    showModal.value = true;
    title.value = '添加';
    resetReactive(form);
    if (record) {
      form.parentId = record.menuId;
      form.menuType = record.menuType === MenuTypeEnum.DIR ? MenuTypeEnum.PAGE : MenuTypeEnum.BTN;
    }
    formRef.value?.clearValidate();
  }

  const formBtnLoading = ref(false);

  function handleConfirm() {
    formRef.value
      .validate()
      .then(() => {
        formBtnLoading.value = true;
        (form.menuId ? MenuApi.update(form) : MenuApi.save(form))
          .then(() => {
            message.success('提交成功');
            showModal.value = false;
            getList();
          })
          .finally(() => {
            formBtnLoading.value = false;
          });
      })
      .catch(() => {});
  }

  function handleDelete(row) {
    Modal.confirm({
      title: '提示',
      content: '确定删除这条记录吗',
      okText: '确定',
      cancelText: '取消',
      onOk: () => {
        MenuApi.delete([row.menuId]).then(() => {
          message.success('操作成功');
          getList();
        });
      },
      onCancel: () => {},
    });
  }
</script>

<style scoped></style>
